#ifndef STM32F103VET6_PROJECT_SYS_CORE_UTILS_H
#define STM32F103VET6_PROJECT_SYS_CORE_UTILS_H

#include "sys_core_conf.h"
#include "sys_core_typedef.h"

typedef enum {
    /**
     * 按照顺序排序
     */
    ABCD,
    /**
     * 按照倒序排序
     */
    DCBA,
    /**
     * 按照双字反转
     */
    CDAB,
    /**
     * 按照单字反转
     */
    BADC,
    AB,
    BA,
} byte_order;
/**
 * @brief 核心工具类，无关硬件的工具类
 * @author scl
 * @note 禁止在此文件中定义与硬件相关的操作函数，如需定义操作硬件相关的函数，请在个人目录下进行创建对应的工具类文件
 */
/**********************************************操作bit位***************************************/
// 写数据Data的第bitNum置为1
#define set_num_bit(Data, bitNum) ((Data) |= (1<<((bitNum)-1)))
// 写数据Data的第bitNum置为0
#define clear_num_bit(Data, bitNum) ((Data) &=~(1<<((bitNum)-1)))
// 读数据Data的第bitNum位的值
#define read_num_bit(Data, bitNum) ((Data) & (1<<((bitNum)-1)))
/********************************convert**************************************/
/**
 * @brief u8 转换 u32
 * @param data 字节数组(注意数组越界问题)
 * @param order 字节序(参数可为： ABCD、CDAB、BADC、DCBA)
 * @return 结果
 */
u32 convert_u8_to_u32(const u8 *data, byte_order order);

/**
 * u32 转换 u8
 * @param dst 目标数组
 * @param data 数据
 * @param order 字节序(参数可为： ABCD、CDAB、BADC、DCBA)
 */
void convert_u32_to_u8(uint8_t *dst, uint32_t data, byte_order order);

/**
 * @brief u8转u16
 * @param a 字节1
 * @param b 字节2
 * @param order 字节序(参数可为： AB、BA)
 * @return 结果
 */
u16 convert_u8_to_u16(u8 a, u8 b, byte_order order);

/**
 * u16转换u8
 * @param dst 目标数组
 * @param data 数据
 * @param order 字节序(参数可为： AB、BA)
 */
void convert_u16_to_u8(uint8_t *dst, u16 data, byte_order order);

/**
 * @brief 字节数组转字符串
 * @param dst 存储字符串的指针
 * @param data 字节数组
 * @param data_len  字节数组长度
 * @param fmt 格式
 * @return 转换长度
 */
int convert_u8_to_str(char *dst, const u8 *data, u16 data_len, char *fmt);

/**
 * 字节数组转10进制字符串
 * @param dst 存储字符串的指针
 * @param data 字节数组
 * @param data_len 字节数组长度
 * @return 转换长度
 */
int convert_u8_to_dec_str(char *dst, const u8 *data, u16 data_len);

/**
 * 字节数组转16进制字符串
 * @param dst 存储字符串的指针
 * @param data 字节数组
 * @param data_len 字节数组长度
 * @return 转换长度
 */
int convert_u8_to_hex_str(char *dst, const u8 *data, u16 len);

/**
 * @brief 字符串口中，转数字(注意最大位数不能超过65535)
 * @param str  "1234"-> 1234
 * @param bitNum
 * @param from_base 基数（2,4,8,10,16）进制
 * @return 数字
 */
u16 convert_str_to_u16(const char *str, u8 bitNum, u8 from_base);

/**
 * @brief float 转字符串
 * @param data 数据
 * @param bitNum 保留位数
 * @return 转换长度
 */
int convert_float_to_str(char *dst, float data, uint16_t bitNum);

/**
 * @brief double 转字符串
 * @param data 数据
 * @param bitNum 保留位数
 * @return 转换长度
 */
int convert_double_to_str(char *dst, double data, uint16_t bitNum);

/**
 * @brief uint8类型转float类型
 * @param data 源数据
 * @return
 */
float convert_u8_to_float(uint8_t *data);

/**
 * @brief float转u8数组中
 * @param dst 目标数组
 * @param data 数据
 */
void convert_float_to_u8(uint8_t *dst, float data);
/********************************************************拷贝***************************************/
/**
 * @brief 按字节数进行拷贝
 * @param dst
 * @param src
 * @param size
 */
void cpy_data(void *dst, void *src, uint16_t size);
/********************************************************比较***************************************/
/**
 * @brief 数据比较
 * @param d1 数据1
 * @param d2 数据2
 * @param cnt 字节数
 * @return 负数:d1<d2; 0: d1=d2; 正数:d1>d2
 */
int cmp_data(void *d1, void *d2, uint16_t cnt);

/**
 * @brief 比较前cnt字节数据是否相等
 * @param d1 数据1
 * @param d2 数据2
 * @param cnt (比较的字节数)
 * @return
 */
bool cmp_equal(void *d1, void *d2, uint16_t cnt);


#endif //STM32F103VET6_PROJECT_SYS_CORE_UTILS_H
